package com.xgame.server.netty.coder;

import com.sun.media.jfxmedia.logging.Logger;
import com.xgame.server.netty.enity.MsgEntity;
import com.xgame.server.netty.proto.Cmdcode;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.MessageToByteEncoder;
import io.netty.handler.codec.MessageToMessageDecoder;
import org.springframework.stereotype.Component;

import java.util.List;

public class NettyMsgDecoder extends LengthFieldBasedFrameDecoder {

    private static final int MAX_FRAME_LENGTH = 134217728;
    private static final int LENGTH_FIELD_OFFSET = 0;
    private static final int LENGTH_FIELD_LENGTH = 4;
    private static final int LENGTH_ADJUSTMENT = 0;
    private static final int INITIAL_BYTES_TO_STRIP = 0;

    public NettyMsgDecoder() {
        super(MAX_FRAME_LENGTH, LENGTH_FIELD_OFFSET, LENGTH_FIELD_LENGTH, LENGTH_ADJUSTMENT, INITIAL_BYTES_TO_STRIP, true);
    }

    public NettyMsgDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength,
                           int lengthAdjustment, int initialBytesToStrip, boolean failFast) {
        super(MAX_FRAME_LENGTH, LENGTH_FIELD_OFFSET, LENGTH_FIELD_LENGTH, LENGTH_ADJUSTMENT,
                INITIAL_BYTES_TO_STRIP, true);
    }

    @Override
    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {

        ByteBuf byteBuf = (ByteBuf) super.decode(ctx, in);
        if (null == byteBuf) {
            return null;
        }

        int total = byteBuf.readableBytes();
        if (total < 16) {
            throw new Exception("Message is too little!");
        }

        //1. 先读取4个字节命令码
        int length = byteBuf.readInt();

        //2. 先读取4个时间戳
        int time = byteBuf.readInt();

        //3. 先读取4个保留字
        int rec = byteBuf.readInt();

        //4. 先读取4个长度
        int cmd = byteBuf.readInt();

        //2.读取剩余的消息体
        byte[] data = new byte[total - 16];// 其它数据为实际数据
        byteBuf.readBytes(data);

        MsgEntity msgVO = new MsgEntity();
        msgVO.setCmdCode(cmd);
        msgVO.setTimeStamp(time);
        msgVO.setReserved(rec);
        msgVO.setData(data);

        return msgVO;
    }

}
